package com.meiyou.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.meiyou.constant.MessageConstant;
import com.meiyou.constant.StatusConstant;
import com.meiyou.context.BaseContext;
import com.meiyou.dto.AddArticleDto;
import com.meiyou.dto.ArticlePageQueryDto;
import com.meiyou.dto.UpdateArticleDto;
import com.meiyou.entity.Article;
import com.meiyou.entity.Collect;
import com.meiyou.entity.Star;
import com.meiyou.exception.ArticleNotFoundException;
import com.meiyou.exception.DataExitsException;
import com.meiyou.exception.NoPermissionException;
import com.meiyou.mapper.*;
import com.meiyou.result.PageResult;
import com.meiyou.service.ArticleService;
import com.meiyou.service.CommentService;
import com.meiyou.utils.CommonUtil;
import com.meiyou.vo.ArticleAdminVo;
import com.meiyou.vo.ArticleCollectVo;
import com.meiyou.vo.ArticleDetailVo;
import com.meiyou.vo.ArticleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @BelongsProject: meiyou
 * @BelongsPackage: com.meiyou.service.impl
 * @Author: 尹晓安
 * @Date: 2023/11/25 18:10
 * @Description:
 */
@Service
public class ArticleServiceImp implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ImageMapper imageMapper;

    @Autowired
    private StarMapper starMapper;

    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private CollectMapper collectMapper;

    @Autowired
    private ReportMapper reportMapper;
    @Value("${my.up-image.path}")
    private String basePath;

    /**
     * 添加文章
     *
     * @param addArticleDto
     * @return
     */
    @Transactional // 开启事务
    @Override
    public void add(AddArticleDto addArticleDto) {

        Article article = new Article();
        article.setTitle(addArticleDto.getTitle());
        // 1.先判断当前文章标题是否重复
        Integer count = articleMapper.select(article);
        // count大于0说明表里面有该标题的文章了
        if (count > 0) {
            // 抛出错误，返回给前端说该文章标题已存在
            throw new DataExitsException("该文章标题" + MessageConstant.ALREADY_EXISTS);
        }
        article.setUserId(BaseContext.getCurrentId());
        BeanUtils.copyProperties(addArticleDto, article);
        // 2.向文章表添加数据
        articleMapper.insert(article);
        // 判断是否有图片
        if (addArticleDto.getImageList().size() > 0) {
            // 3.向图片表里面添加数据
            imageMapper.insertBatch(article.getId(), addArticleDto.getImageList());
        }
    }

    /**
     * 修改文章
     *
     * @param updateArticleDto
     * @return
     */
    @Transactional // 开启事务
    @Override
    public void updateArticle(UpdateArticleDto updateArticleDto) {

        // 创建文章对象
        Article article = new Article();
        article.setId(updateArticleDto.getId());
        // 1.检查有无该文章
        Integer count = articleMapper.select(article);
        // count小于等于0，说明没有改文章，抛出错误没有改文章
        if (count <= 0) {
            throw new ArticleNotFoundException(MessageConstant.ARTICLE_NOT_FOUND);
        }
        // 将数据复制给文章对象
        BeanUtils.copyProperties(updateArticleDto, article);
        // 修改文章后将文章状态为审核中
        article.setStatus(StatusConstant.EXAMINE);
        // 2.修改文章
        articleMapper.update(article);
        // 3.删除该文章的所有图片（先全删再添加达到更新效果）
        imageMapper.removeBatch(article.getId());
        if (updateArticleDto.getImageList().size() > 0) {
            // 4.添加该文章图片到数据表
            imageMapper.insertBatch(article.getId(), updateArticleDto.getImageList());
        }
    }

    /**
     * 根据用户id获取文章,分页
     *
     * @param articlePageQueryDto
     * @return
     */
    @Override
    public PageResult getArticleByUserId(ArticlePageQueryDto articlePageQueryDto) {

        // 启动分页查询
        PageHelper.startPage(articlePageQueryDto.getPage(), articlePageQueryDto.getPageSize());

        Page<ArticleVo> articleVo = articleMapper.page(BaseContext.getCurrentId(), articlePageQueryDto.getKeyword());

        articleVo.getResult().forEach(item -> {
            // 获取该文章的图片
            List<String> imageList = imageMapper.select(item.getId());
            item.setImageList(imageList);

            // 获取点赞数
            Star star = new Star();
            star.setArticleId(item.getId());
            Integer starCount = starMapper.select(star);
            item.setStarNum(starCount);
            // 获取用户有无点赞
            star.setUserId(BaseContext.getCurrentId());
            Integer starUserCount = starMapper.select(star);
            item.setStar(starUserCount > 0 ? 1 : 0);

            // 获取评论数
            item.setCommentNum(commentMapper.getCommentNumByArticleId(item.getId()));
        });

        return new PageResult(articleVo.getTotal(), articleVo.getResult());
    }

    /**
     * 分页获取文章
     *
     * @param articlePageQueryDto
     * @return
     */
    @Override
    public PageResult getArticle(ArticlePageQueryDto articlePageQueryDto) {
        // 启动分页查询
        PageHelper.startPage(articlePageQueryDto.getPage(), articlePageQueryDto.getPageSize());

        Page<ArticleVo> articleVo = articleMapper.page(null, articlePageQueryDto.getKeyword());

        articleVo.getResult().forEach(item -> {
            // 获取该文章的图片
            List<String> imageList = imageMapper.select(item.getId());
            item.setImageList(imageList);

            // 获取点赞数
            Star star = new Star();
            star.setArticleId(item.getId());
            Integer starCount = starMapper.select(star);
            item.setStarNum(starCount);
            // 获取用户有无点赞
            star.setUserId(BaseContext.getCurrentId());
            Integer starUserCount = starMapper.select(star);
            item.setStar(starUserCount > 0 ? 1 : 0);

            // 获取评论数
            item.setCommentNum(commentMapper.getCommentNumByArticleId(item.getId()));

        });

        return new PageResult(articleVo.getTotal(), articleVo.getResult());
    }

    /**
     * 删除文章
     *
     * @param id 文章id
     * @return
     */
    @Transactional // 开启事务
    @Override
    public void deleteArticle(Long id) {
        Article article = Article.builder().id(id).build();
        // 1.检查有无该文章
        Integer count = articleMapper.select(article);
        // count小于等于0，说明没有改文章，抛出错误没有改文章
        if (count <= 0) {
            throw new ArticleNotFoundException(MessageConstant.ARTICLE_NOT_FOUND);
        }
        // 2.删除文章
        articleMapper.deleteById(id);
        // 删除这篇文章的所有评论
        commentMapper.removeByArticleId(id);
        // 删除这篇文章的举报
        reportMapper.removeByArticleId(id);
        // 删除点赞
        starMapper.removeByArticleId(id);
        // 删除收藏
        collectMapper.removeByArticleId(id);
        // 获取该文章的所有图片，后面要根据图片名来删除本地的图片
        List<String> imageList = imageMapper.select(id);
        // 3.删除数据表图片
        imageMapper.removeBatch(id);
        // 4.删除本地图片
        imageList.forEach(item -> {
            CommonUtil.deleteFile(basePath + item);
        });
    }

    /**
     * 审核文章
     *
     * @param id     文章id
     * @param status 文章状态，1审核通过、0审核不通过、2审核中
     * @return
     */
    @Override
    public void examineArticle(Long id, Integer status) {

        // 1.判断当前用户是否是管理员
        // 获取当前用户id
        Long userId = BaseContext.getCurrentId();
        Integer role = userMapper.selectRole(userId);
        // role等于0位普通用户，没有权限
        if (role == 0) {
            throw new NoPermissionException(MessageConstant.NO_PERMISSION);
        }

        Article article = Article.builder().id(id).build();
        // 2.检查有无该文章
        Integer count = articleMapper.select(article);
        // count小于等于0，说明没有改文章，抛出错误没有改文章
        if (count <= 0) {
            throw new ArticleNotFoundException(MessageConstant.ARTICLE_NOT_FOUND);
        }
        article.setStatus(status);
        // 3.修改文章状态
        articleMapper.update(article);
    }

    /**
     * 分页获取用户点赞文章
     *
     * @param articlePageQueryDto
     * @return
     */
    @Override
    public PageResult getStarArticle(ArticlePageQueryDto articlePageQueryDto) {
        // 启动分页查询
        PageHelper.startPage(articlePageQueryDto.getPage(), articlePageQueryDto.getPageSize());

        Page<ArticleVo> articleVo = articleMapper.starPage(BaseContext.getCurrentId());

        articleVo.getResult().forEach(item -> {
            // 获取该文章的图片
            List<String> imageList = imageMapper.select(item.getId());
            item.setImageList(imageList);

            // 获取点赞数
            Star star = new Star();
            star.setArticleId(item.getId());
            Integer starCount = starMapper.select(star);
            item.setStarNum(starCount);
            // 获取用户有无点赞
            star.setUserId(BaseContext.getCurrentId());
            Integer starUserCount = starMapper.select(star);
            item.setStar(starUserCount > 0 ? 1 : 0);

            // 获取评论数
            item.setCommentNum(commentMapper.getCommentNumByArticleId(item.getId()));
        });

        return new PageResult(articleVo.getTotal(), articleVo.getResult());
    }

    /**
     * 分页获取用户收藏文章
     *
     * @param articlePageQueryDto
     * @return
     */
    @Override
    public PageResult getCollectArticle(ArticlePageQueryDto articlePageQueryDto) {
        // 启动分页查询
        PageHelper.startPage(articlePageQueryDto.getPage(), articlePageQueryDto.getPageSize());

        Page<ArticleCollectVo> articleCollectVo = articleMapper.collectPage(BaseContext.getCurrentId());

        articleCollectVo.getResult().forEach(item -> {
            // 获取该文章的图片
            List<String> imageList = imageMapper.select(item.getId());
            item.setImageList(imageList);
        });

        return new PageResult(articleCollectVo.getTotal(), articleCollectVo.getResult());
    }

    /**
     * 获取文章详情
     *
     * @param id 文章id
     * @return
     */
    @Override
    public ArticleDetailVo getArticleDetail(Long id) {

        Article article = Article.builder().id(id).build();
        // 查询是否有该文章
        Integer count = articleMapper.select(article);

        if (count <= 0) {
            throw new ArticleNotFoundException(MessageConstant.ARTICLE_NOT_FOUND);
        }
        // 查询文章数据
        ArticleDetailVo articleDetailVo = articleMapper.selectById(id);

        Integer commentNum = commentMapper.selectCommentNum(null, id);
        articleDetailVo.setCommentNum(commentNum);
        // 查询是否点赞
        Star star = Star.builder().
                articleId(id).
                build();

        Integer starCount = starMapper.select(star);
        articleDetailVo.setStarNum(starCount);

        star.setUserId(BaseContext.getCurrentId());
        starCount = starMapper.select(star);
        articleDetailVo.setStar(starCount > 0 ? 1 : 0);
        // 查询是否收藏
        Collect collect = Collect.builder().
                articleId(id).
                build();

        Integer collectCount = collectMapper.select(collect);
        articleDetailVo.setCollectNum(collectCount);

        collect.setUserId(BaseContext.getCurrentId());

        collectCount = collectMapper.select(collect);
        articleDetailVo.setCollect(collectCount > 0 ? 1 : 0);

        return articleDetailVo;
    }

    /**
     * 管理员获取文章（进行审核）根据文章状态获取
     *
     * @param status 文章状态，1审核通过、0审核不通过、2审核中
     * @return
     */
    @Override
    public PageResult getAdminArticle(Integer status, ArticlePageQueryDto articlePageQueryDto) {
        // 启动分页查询
        PageHelper.startPage(articlePageQueryDto.getPage(), articlePageQueryDto.getPageSize());

        Page<ArticleAdminVo> articleAdminVo = articleMapper.pageByStatus(status);

        return new PageResult(articleAdminVo.getTotal(), articleAdminVo.getResult());
    }
}
